import Vue from "vue"
import VueRouter from "vue-router"
import routes from "./routes"
import store from "@/store"

Vue.use(VueRouter)

const router = new VueRouter({
  mode: "history",
  routes: routes,
  //控制路由切换的时候,滚动条的位置
  scrollBehavior() {
    return {
      x: 0,
      y: 0,
    }
  },
})

//路由前置守卫进行路由跳转的鉴权操作
//1.设置一个白名单,控制哪些路由不需要登录就可以访问的
const whitePath = [
  "home",
  "login",
  "search",
  "register",
  "detail",
  "addcartsuccess",
]

//2. 配置全局前置守卫
router.beforeEach(async (to, from, next) => {
  //从vuex中拿到token
  const token = store.state.user.token
  //3.判断是否携带token，如果有token的情况
  if (token) {
    //5.判断要去的地方是不是登录页,如果是则直接回到首页（因为此时已经在登录页面了）
    if (to.name === "login") {
      next("/home")
    } else {
      // 6.现在有token去的不是登录页,判断我们是否拥有用户信息(一般来说,登录只会返回token,然后我们一旦有token都会再次发送请求请求用户的详细信息)
      // !! 表示将目标转为布尔值，这里需要判断userInfo里是否有nickName，也可以认为判断有token的情况下是否有用户信息
      const isUserInfo = !!store.state.user.userInfo.nickName
      if (isUserInfo) {
        //有token 又有用户信息 则完全放行
        next()
      } else {
        //没有用户信息时则需要向后端请求用户信息
        //dispatch方法只是调用getUserInfo方法的一种方式,所以他的返回值和getUserInfo的返回值一致,都是返回promise实例
        //异常处理,一旦刷新,token是持久化存的,用户信息不是持久化的,所以刷新以后一定会重新获取用户信息,一旦token过期或者token被篡改,则无法正常获取数据,此时应该清除掉已经报废的token,并且重新让用户登录
        try {
          //这里要加await  作用是等待getUserInfo请求的结果出来之后再决定是否放开权限
          await store.dispatch("user/getUserInfo")
          //得到用户信息则放开权限
          next()
        } catch (error) {
          //如果获取用户信息异常,说明token已经不能用了,需要清掉重新登录
          store.dispatch("user/resetToken")
          //调用完清理报废的token后跳转登录页
          next("/login")
        }
      }
    }
  } else {
    //4.没有token的情况下，需要判断去往的页面在不在白名单中
    if (whitePath.includes(to.name)) {
      //如果导航去往的页面在白名单中，则直接放行
      next()
    } else {
      //如果导航去往的页面不在白名单中，则说明需要token鉴权，此时就需要登录了
      next("/login")
    }
  }
})

export default router
